//引入定义小仓库的函数
import { defineStore } from 'pinia';
import { getToken, removeToken, setToken } from '../utils/token-utils';
import type { UserInfoState } from './interface';
//element-plus提供的消息提示组件
import { ElMessage } from 'element-plus'
//引入vue-router里面配置好的路由信息
import { staticRoutes, allAsyncRoutes, anyRoute } from '@/router/routes'
//引入发送请求的函数
import { reqLogin, reqLogOut, reqUserInfo } from '@/api/acl/login';
//引入lodash
import _ from 'lodash';
//引入router
import router from '@/router';
/**
 * 用户信息
 * @methods setUserInfos 设置用户信息
 */

//计算出当前用户将来需要动态追加的异步路由结果
//两个参数，第一个参数路由文件里面对外暴露的所有异步路由组件，
//第二个参数，当前用户登录成功，用户信息里面所包含的动态路由信息（需要动态注册的信息）
//定义一个函数判断用户登录以后展示的页面信息，后面可以随时调用
const findUserAsyncRoutes = (allAsyncRoutes: any, routes: any) => {
  // 过滤出用户需要动态添加的异步路由器
  return allAsyncRoutes.filter((item: any) => {
    //item过滤一级的路由
    if (routes.indexOf(item.name) != -1) {
      //过滤二级/三级/n级路由
      if (item.children && item.children.length > 0) {
        item.children = findUserAsyncRoutes(item.children, routes)
      }
      return true
    }
  })
};
export const useUserInfoStore = defineStore('userInfo', {

  state: (): UserInfoState => ({
    token: getToken() as string,//token
    name: '',//用户名
    avatar: '',//头像
    menuRoutes: [],//左侧菜单展示的数据
    buttonsList:[]
  }),

  actions: {
    //点击登录按钮，仓库需要发送登录请求
    async login(username: string, password: string) {
      //登录请求：如果登录成功，会返回token
      //token：请求成功才有token，区分是不是用户的唯一标识符
      //token需要持久化存储
      try {
        let result = await reqLogin({ username, password });
        //仓库储存token
        this.token = result.token;
        //持久化存储token(老师已经定义好持久化储存地址setToken直接用即可)
        setToken(result.token);
        return '登录成功'
      } catch (error) {
        return Promise.reject('登陆失败')
      }
    },

    //获取用户信息
    async getInfo() {
      try {
        //登录成功获取用户信息：一定要携带token
        let result = await reqUserInfo();
        //获取用户的信息：头像和名字
        this.name = result.name;
        this.avatar = result.avatar;
        //仓库存储当前用户按钮的权限
        this.buttonsList = result.buttons;
        //先计算出当前用户需要展示的异步路由，定义异步路由和服务器返回的数据routes进行对比
        let userRegisterAsyncRoute = findUserAsyncRoutes(_.cloneDeep(allAsyncRoutes),result.routes)
        //调用方法，动态添加用户注册异步路由+任意路由
        this.setRoute([...userRegisterAsyncRoute,anyRoute])
        //修改仓库里面menuRoutes的属性值
        this.menuRoutes = [...staticRoutes,...userRegisterAsyncRoute];
        return 'ok'
      } catch (error) {
        return Promise.reject(error)
      }
    },
    //动态添加路由
    setRoute(registerRoute:any){
      //动态追加路由
      registerRoute.forEach((item:any)=>{
        router.addRoute(item);
      })
    },
    //退出登录取消token
    async reset() {
      try {
        //退出登录请求
        await reqLogOut();
        //删除本地存储的token
        removeToken();
        //清空仓库自身的关于用户信息的数据
        this.token = ''
        this.name = ''
        this.avatar = ''
        //重置路由
        this.resetRoute();
        return 'ok';
      } catch (error) {
        return Promise.reject(error);
      }
    },
    //重置路由的方法
    resetRoute(){
      //当前用户退出登录，应该清空全部异步路由
      //获取当前用户全部路由信息
      let allRoutes = router.getRoutes();
      //用户退出登录，全部的路由清除
      allRoutes.forEach((item:any)=>{
        //删除全部路由
        router.removeRoute(item.name);
      });
      //动态添加常量路由
      staticRoutes.forEach((item:any)=>{
        router.addRoute(item);
      })
    }
  },
});
